function assert(val) {
  if(!val ) {
    throw new Error(9101, "assert error");
  }
}

function TestCase() {
  this.bufferSummary = "\n";
  
  this.setUp = function() {
    this.log="setUp ";
  };
  
  this.tearDown = function() {
    this.log=this.log+"tearDown ";
  };
  
  this.run = function(params) {
    for(var i=0;i<params.length;i++) {
      result = new TestResult();
      this.runFunc(params[i], result);
      this.bufferSummary += params[i].constructor.name + ":" + result.summary() + "\n";
    }  
  }  
  
  this.runFunc = function(testObj, result) {
    this.setUp();
    validFuncs = this.extractFuncs(testObj);
    for(var i=0;i<validFuncs.length;i++) {
      result.testStarted();
      try {
        var callName = "testObj."+validFuncs[i]+"();";
        eval(callName);
      } catch(e) {
        Logger.log(e);
        result.testFailed();
      } 
    } 
    this.tearDown();
  };
  
  this.extractFuncs = function(testObj) {
    validFuncs = new Array();  
    for(var aFunc in (testObj)) {
      if(aFunc.substring(0,4) == "test") {
        validFuncs.push(aFunc);
      }
    }
    return validFuncs;
  }  
  
  this.summary = function() {
    return this.bufferSummary;
  } 
    
}

function TestResult() {
  this.runCount=0;
  this.failCount=0;
  
  this.testStarted = function() {
    this.runCount += 1;
  }
  
  this.testFailed = function() {
    this.failCount += 1;
  }
  
  this.summary = function() {
    return this.runCount+" run, "+this.failCount+" failed";
  };  
}

function runTest() {
  test = new TestCase();
  test.run(arguments);
  Logger.log(test.summary());
}  
